package com.cyh.testcustomui;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

public class MessageBubbleView extends View {
    //两个圆的圆心
    private PointF mFixationPoint,mDragPoint;
    private int mDragRadius = 20;
    private int mFixRadius = 10;
    private int mFixRadiusMax = 10;
    private Paint mPaint;
    public MessageBubbleView(Context context) {
        this(context, null);
    }

    public MessageBubbleView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MessageBubbleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.RED);

        /*initPoint(100, 100);
        updateDragPoint(100, 100);

        post(new Runnable() {
            @Override
            public void run() {
                invalidate();
            }
        });*/
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                float downX = event.getX();
                float downY = event.getY();
                initPoint(downX, downY);
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = event.getX();
                float moveY = event.getY();
                updateDragPoint(moveX, moveY);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        invalidate();
        return true;
    }

    private void updateDragPoint(float moveX, float moveY) {
        mDragPoint.x = moveX;
        mDragPoint.y = moveY;
    }

    private void initPoint(float downX, float downY) {
        mFixationPoint = new PointF(downX, downY);
        mDragPoint = new PointF(downX, downY);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mDragPoint == null || mFixationPoint == null) {
            return;
        }
        Log.i("MESSAGE", "----x: " + mDragPoint.x + ", y:" + mDragPoint.y);
        canvas.drawCircle(mDragPoint.x, mDragPoint.y, mDragRadius, mPaint);

        //两个圆心直接的距离
        double distanc = getDistance(mDragPoint, mFixationPoint);
        mFixRadius = (int)(mFixRadiusMax - distanc/14);

        Path bezeierPath = getBezeierPath();
        if(mFixRadius < 2) {
            mFixRadius = 2;
        }
        canvas.drawCircle(mFixationPoint.x, mFixationPoint.y, mFixRadius, mPaint);

        if(bezeierPath != null) {
            canvas.drawPath(bezeierPath, mPaint);
        }
    }

    private Path getBezeierPath() {
        Path bezeierPath = new Path();
        float dy = mDragPoint.y - mFixationPoint.y;
        float dx = mDragPoint.x - mFixationPoint.x;
        float tanA = dy/dx;
        double arcTanA = Math.atan(tanA);

        float p0x = (float)(mFixationPoint.x + mFixRadius * Math.sin(arcTanA));
        float p0y = (float)(mFixationPoint.y - mFixRadius * Math.cos(arcTanA));

        float p1x = (float)(mDragPoint.x + mDragRadius * Math.sin(arcTanA));
        float p1y = (float)(mDragPoint.y - mDragRadius * Math.cos(arcTanA));

        float p2x = (float)(mDragPoint.x - mDragRadius * Math.sin(arcTanA));
        float p2y = (float)(mDragPoint.y + mDragRadius * Math.cos(arcTanA));

        float p3x = (float)(mFixationPoint.x - mFixRadius * Math.sin(arcTanA));
        float p3y = (float)(mFixationPoint.y + mFixRadius * Math.cos(arcTanA));

        bezeierPath.moveTo(p0x, p0y);
        PointF controlPoint = getConrolPoint();
        bezeierPath.quadTo(controlPoint.x, controlPoint.y, p1x, p1y);

        bezeierPath.lineTo(p2x, p2y);
        bezeierPath.quadTo(controlPoint.x, controlPoint.y, p3x, p3y);

        bezeierPath.close();

        return bezeierPath;

    }

    private PointF getConrolPoint() {
        return new PointF((mDragPoint.x - mFixationPoint.x)/2, (mDragPoint.y - mFixationPoint.y)/2);
    }

    private double getDistance(PointF dragPoint, PointF fixationPoint) {
        return Math.sqrt((dragPoint.x - fixationPoint.x) * (dragPoint.x - fixationPoint.x) + (dragPoint.y - fixationPoint.y) * (dragPoint.y - fixationPoint.y));
    }
}
